<!-- 鼠标交互，投掷小球 -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>鼠标交互，投掷小球</title>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script src="../utils.js"></script>
<script>
    // 小球绘制
    class Ball {
        constructor(options) {
            this.x = 0;
            this.y = 0;
            this.r = 200;
            this.fillStyle = 'blue';
            this.strokeStyle = 'black';
            // 小球缩放
            this.scaleX = 1;
            this.scaleY = 1;
            // 定义小球移动速度
            this.vx = 0;
            this.vy = 0;
            // 小球透明度
            this.alpha = 1;
            Object.assign(this, options);
            return this;
        }
        render(ctx) {
            let { x, y, r, fillStyle, strokeStyle, scaleX, scaleY, alpha } = this;
            // 保存绘图环境
            ctx.save();
            // 开始绘制
            // ctx.beginPath();
            ctx.beginPath();
            ctx.translate(x, y);
            ctx.scale(scaleX, scaleY);
            ctx.strokeStyle = strokeStyle;
            ctx.fillStyle = fillStyle;

            ctx.globalAlpha = alpha;

            ctx.arc(0, 0, r, 0, Math.PI * 2);


            ctx.fill();
            ctx.stroke();
            ctx.restore();
            ctx.closePath();
            return this;
        }
        // 判断点是否在图形内部
        isInside(x, y) {
            let dis = Math.sqrt(Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2))
            return dis < this.r;
        }
    }
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    let w = canvas.width = 500;
    let h = canvas.height = 500;
    let mouse = c.getOffset(canvas);
    let ball = new Ball({
        x: w / 2,
        y: h / 2,
        r: 50,
        fillStyle: 'red',
        strokeStyle: 'black',
        scaleX: 1,
        scaleY: 1,
        alpha: 1,
        vx: c.rand([-10, 10]),
        vy: c.rand([0, 10]),
    });
    console.log(ball.x, ball.y);

    ball.render(ctx);
    // 用来标记两种运动状态
    let isMove = false;
    // 鼠标点击小球，距离圆心的差
    let dx, dy;
    // 用于记录时间差
    let time = 0;
    // 记录小球初始位置，用于做投掷操作
    let sx, sy, ex, ey;
    canvas.addEventListener('mousedown', (e) => {
        console.log('down');
        ctx.clearRect(0, 0, w, h);
        if (ball.isInside(mouse.x, mouse.y)) {
            console.log('in');
            isMove = true;
            dx = mouse.x - ball.x;
            dy = mouse.y - ball.y;
            // 获取初始的时间戳和小球位置
            time = (new Date().getTime()) / 1000;
            sx = ball.x;
            sy = ball.y;
            canvas.addEventListener('mousemove', mouseMove);
            canvas.addEventListener('mouseup', mouseUp);
        }
    });

    /**
     * 鼠标移动事件
     * @param {Object} e 
     */
    function mouseMove(e) {
        console.log('move')
        ball.x = mouse.x - dx;
        ball.y = mouse.y - dy;
    }

    /**
     * 鼠标松开事件
     * @param {Object} e 
     */
    function mouseUp(e) {
        isMove = false;
        console.log('false');
        // 恢复小球运动速度
        vx = ball.vx;
        vy = ball.vy;
        canvas.removeEventListener('mousemove', mouseMove);
        canvas.removeEventListener('mouseup', mouseUp);
    }


    let vx = ball.vx, vy = ball.vy;
    (function move() {
        window.requestAnimationFrame(move);
        ctx.clearRect(0, 0, w, h);
        // 重力加速度

        if (!isMove) {
            vy += 0.1;
            // console.log('is false', ball.vx, ball.vy);
            ball.x += vx;
            ball.y += vy;
            if (ball.x + ball.r > w || ball.x - ball.r < 0) {
                vx *= -0.8;
            }
            if (ball.y + ball.r > h || ball.y - ball.r < 0) {
                vy *= -0.8;
            }
        } else {
            ex = ball.x;
            ey = ball.y;
            etime = (new Date().getTime()) / 1000;

            vx = (ex - sx) / (etime - time);
            vy = (ey - sy) / (etime - time);
            vy += 0.1;
        }


        ball.render(ctx);
    })()

</script>

</html>